package cqie.cn.frame.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import cqie.cn.frame.common.SelectListItem;
import cqie.cn.frame.entity.SysRole;
import cqie.cn.frame.entity.SysUser;
import cqie.cn.frame.entity.UserRole;
import cqie.cn.frame.entity.bo.SysUserBo;
import cqie.cn.frame.entity.qo.SysUserQo;
import cqie.cn.frame.entity.vo.SysMenuVo;
import cqie.cn.frame.entity.vo.SysUserVo;
import cqie.cn.frame.service.ISysRoleService;
import cqie.cn.frame.service.ISysUserService;
import cqie.cn.frame.service.IUserRoleService;
import cqie.cn.frame.utils.MD5Utils;
import cqie.cn.frame.utils.ResultVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static cqie.cn.frame.utils.PageParam.PAGE_NUMBER;
import static cqie.cn.frame.utils.PageParam.PAGE_SIZE;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author wangLin
 * @since 2021-09-22
 */
@Api(tags = "01系统管理--01用户管理")
@ApiModel(value = "用户管理")
@RestController
@RequestMapping("/frame/sysUser")
public class SysUserController {

    @Resource
    private ISysUserService userService;

    @Resource
    private IUserRoleService userRoleService;

    @Resource
    private ISysRoleService roleService;

    //新增用户
    @ApiOperation(value = "新增用户", notes = "", response = SysUserBo.class)
    @PostMapping(value = "/add")
    public ResultVo add(@RequestBody SysUserBo bo) {
        try {
            //1-先插入用户
            SysUser sysUser = new SysUser();
            BeanUtils.copyProperties(bo, sysUser);
            //处理密码
            sysUser.setPassword(MD5Utils.EncodeMD5(bo.getPassword()));
            userService.save(sysUser);
            bo.setId(sysUser.getId());//返回用的

            //2-插入用户角色
            if (bo.getRoleIdList() != null) {
                ArrayList<UserRole> userRoleList = new ArrayList<>();
                //遍历用户角色，将用户id和角色id存到 userRole 对象中，装到 userRoleList 集合中，在将集合中数据存入userRole表中
                bo.getRoleIdList().forEach(x -> {
                    UserRole userRole = new UserRole();
                    userRole.setRoleId(x);
                    userRole.setUserId(sysUser.getId());//mybatis 新增后 会回写id
                    userRoleList.add(userRole);
                });
                userRoleService.saveBatch(userRoleList);
            }
            return ResultVo.success("新增成功！", bo);

        } catch (Exception e) {
            return ResultVo.error("新增失败");
        }
    }

    //删除
    @ApiOperation(value = "删除用户", notes = "")
    @DeleteMapping(value = "/remove")
    public ResultVo remove(Long id) {

        Boolean falg = false;
        //1-在 user_role 表中，把userid删除；删除用户角色关系
        QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", id);

        //如果把userid删除成功
        if (userRoleService.remove(wrapper)) {
            //2-在 sys_user 表中，删除 user用户
            userService.removeById(id);
            return ResultVo.success("删除成功");
        }

        return ResultVo.error("删除失败");
    }

    //修改
    @ApiOperation(value = "修改用户", notes = "", response = SysUserBo.class)
    @PostMapping(value = "/edit")
    @ApiOperationSupport(ignoreParameters = {"createTime", "updateTime"})
    public ResultVo edit(@RequestBody SysUserBo bo) {
        try {
            //获取修改前的值
            SysUser crude = userService.getById(bo.getId());
            //方案一：先删除，后加    方案二：比对，添加或者修改或删除
            //1-修改用户表中 信息
            SysUser sysUser = new SysUser();
            BeanUtils.copyProperties(bo, sysUser);//将 po 类中的字段 复制到 sysUser 中
            sysUser.setPassword(crude.getPassword());
            userService.updateById(sysUser);

            //2-删除 用户角色表中 userId
            QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", bo.getId());
            userRoleService.remove(wrapper);

            //循环遍历，添加用户的id和角色id
            if (bo.getRoleIdList() != null) {
                List<UserRole> userRoleList = new ArrayList<>();
                bo.getRoleIdList().forEach(x -> {
                    UserRole userRole = new UserRole();
                    userRole.setRoleId(x);
                    userRole.setUserId(bo.getId());
                    userRoleService.saveBatch(userRoleList);
                });
            }
            return ResultVo.success("修改成功", bo);
        } catch (Exception e) {
            return ResultVo.error(e.getMessage());
        }
    }

    // 查询
    @PostMapping("/listPaged")
    @ApiOperation(value = "分页列表", notes = "", response = SysUserVo.class)
    public ResultVo listPaged(@RequestBody SysUserQo qo) {

        try {
            Page<SysUser> page = new Page<>(PAGE_NUMBER, PAGE_SIZE);
            //查询添加
            //1-用户名模糊查找
            QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
            if (!StringUtils.isEmpty(qo.getName())) {
                wrapper.like("name", qo.getName());
            }
            //1.2-状态
            if (qo.getStatus() != null) {
                wrapper.eq("status", qo.getStatus());
            }
            //2-执行分页查询
            IPage<SysUser> datas = userService.page(page, wrapper);
            //3-生成返回值
            //映射状态
            // data数据中 得到集合 转成流（可以用java8的语法）遍历集合（需要的字段） 去重  转成集合
            List<Long> userIdList = datas.getRecords().stream().map(x -> x.getId()).distinct().collect(Collectors.toList());
            List<UserRole> allUserRole = new ArrayList<>();
            if (userIdList.size() > 0) {
                QueryWrapper<UserRole> qwUserRole = new QueryWrapper<>();
                qwUserRole.in("user_id", userIdList);
                allUserRole = userRoleService.list(qwUserRole); //只查当前用户相关的角色
            }

            List<SysRole> allRole = new ArrayList<>();
            List<Long> roleIdList = allUserRole.stream().map(x -> x.getRoleId()).distinct().collect(Collectors.toList());
            if (roleIdList.size() > 0) {
                QueryWrapper<SysRole> qwRole = new QueryWrapper<>();
                qwRole.in("id", roleIdList);
                allRole = roleService.list(qwRole);
            }

            ArrayList<SysUserVo> list = new ArrayList<>();
            IPage<SysUserVo> ret = new Page<>();
            BeanUtils.copyProperties(datas, ret); //把data字段复制到ret字段
            for (SysUser mo : datas.getRecords()) {
                SysUserVo userVo = new SysUserVo();
                //映射---状态
                BeanUtils.copyProperties(mo, userVo);
                userVo.setRoleNames(mo.getStatus() == 0 ? "正常" : "禁用");
                //映射---担任角色
                List<Long> findUserRoleIdList = allUserRole.stream()
                        .filter(x -> x.getUserId().equals(mo.getId()))
                        .map(x -> x.getRoleId())
                        .distinct()
                        .collect(Collectors.toList());
                List<String> findRoleNameList = allRole.stream()
                        .filter(x -> findUserRoleIdList.contains(x.getId()))
                        .map(x -> x.getName())
                        .distinct()
                        .collect(Collectors.toList());
                //字符串分隔符 集合用分隔符连起来
                userVo.setRoleNames(String.join("|", findRoleNameList));
                list.add(userVo);
            }
            ret.setRecords(list);
            return ResultVo.success("查询成功", ret);
        } catch (Exception e) {
            return ResultVo.error(e.getMessage());
        }
    }


    //数据准备--获取角色备选列表
    @ApiOperation(value = "获取角色备选列表", notes = "", response = SelectListItem.class)
    @GetMapping(value = "/listRoles")
    public ResultVo listRoles() {
        try {
            List<SelectListItem> listItems = new ArrayList<>();
            List<SysRole> roleList = roleService.list();
            roleList.forEach(x -> {
                listItems.add(new SelectListItem(x.getName(), x.getId().toString()));
            });
            return ResultVo.success("数据准备成功", listItems);
        } catch (Exception e) {
            return ResultVo.error(e.getMessage());
        }
    }

    //查看详情
    @ApiOperation(value = "查看详情", notes = "", response = SysMenuVo.class)
    @GetMapping(value = "/details")
    public ResultVo details(Long id) {

        try {
            //1-获取mo
            SysUser mo = userService.getById(id);

            //2-映射成vo
            SysUserVo vo = new SysUserVo();
            BeanUtils.copyProperties(mo, vo);
            //映射--准备
            //映射--状态
            vo.setStatusName(mo.getStatus() == 0 ? "正常" : "禁用");
            //映射--角色
            QueryWrapper<SysRole> qw = new QueryWrapper<>();
            qw.inSql("id", "select role_id from user_role where user_id=" + id);
            List<SysRole> findRoleList = roleService.list(qw);
//            vo.setRoleNames(String.join("|", findRoleList.stream().map(x -> x.getName()).collect(Collectors.toList())));
            vo.setRoleNames(String.join("|", findRoleList.stream()
                    .map(SysRole::getName)
                    .collect(Collectors.toList())));
            //隐藏密码
//            vo.setPassword(null);
            vo.setPassword("******");
            //3-返回vo
            return ResultVo.success("查看成功！", vo);
        } catch (Exception e) {
            return ResultVo.success("查看失败！");
        }


    }
}

